﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using Artem.Google.UI;
using VO.Business.Controllers;
using VO.Business.Utils;
using VO.Entities;
using VO.Web.Utils;

namespace VO.Web
{
    public enum EditMode
    {
        List,
        Edit
    }

    public partial class MyTracks : System.Web.UI.Page
    {

        public Track EditedTrack
        {
            get { return Session["EditedTrack"] as Track; }
            set { Session["EditedTrack"] = value; }
        }

        private User _user;
        public User GetCurrentUser()
        {
            if (_user == null)
            {
                MembershipUser mUser = Membership.GetUser();
                Guid idMembership = new Guid(mUser.ProviderUserKey.ToString());
                _user = UsersController.GetUserByIdMembership(idMembership);
                Session["UserId"] = _user.Id;
            }
            return _user;
        }

        public EditMode CurrentEditMode
        {
            get
            {
                if (Session["CurrentEditMode"] != null)
                    return (EditMode)Session["CurrentEditMode"];
                return EditMode.List;
            }
            set { Session["CurrentEditMode"] = value; }
        }


        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                GetCurrentUser();
                ChangeDisplayMode(EditMode.List);
                PopulateTrackCategories();

                MembershipUser myObject = Membership.GetUser();
                if (myObject != null)
                {
                    //
                }
            }
            UpdateDisplayMode();
        }

        private void PopulateTrackCategories()
        {
            List<TrackCategory> lstCat = TracksCategoriesController.GetTracksCategories();
            cboTrackCategory.Items.Clear();
            lstCat.ForEach(c => cboTrackCategory.Items.Add(new ListItem(c.CategoryName, c.Id.ToString())));
        }

        protected void btnAddTrack_Click(object sender, EventArgs e)
        {
            Track newTrack = new Track();
            newTrack.UserId = GetCurrentUser().Id;
            newTrack.Level = 1;
            newTrack.Locked = false;
            newTrack.TrackName = "Enter new track name";
            newTrack.TrackCategoryId = 1;

            EditedTrack = newTrack;
            PopulateTrackDetails(newTrack);

            ChangeDisplayMode(EditMode.Edit);

            txtTracksName.Focus();
            txtTracksName.Attributes.Add("onfocus", "javascript:this.select();");
        }

        protected void btnCancel_Click(object sender, EventArgs e)
        {
            ChangeDisplayMode(EditMode.List);
        }


        protected void gvTrackList_RowCommand(object sender, GridViewCommandEventArgs e)
        {
            if (e.CommandName == "EditDetails")
            {
                //prepare track for editing
                Guid trackId = new Guid(e.CommandArgument.ToString());
                Track tr1 = TracksController.GetTrack(trackId);
                if (!tr1.Locked)
                {
                    PopulateTrackDetails(tr1);
                    EditedTrack = tr1;

                    ChangeDisplayMode(EditMode.Edit);

                    FitTrackInView();
                }
                else
                {
                    ChangeDisplayMode(EditMode.List);
                }
            }
            if (e.CommandName == "DeleteTrack")
            {
                //detele track
                Guid trackId = new Guid(e.CommandArgument.ToString());
                TracksController.DeleteTrack(trackId);

                ChangeDisplayMode(EditMode.List);
                gvTrackList.DataBind();
            }
        }

        private void ChangeDisplayMode(EditMode mode)
        {
            CurrentEditMode = mode;
            UpdateDisplayMode();
        }

        private void UpdateDisplayMode()
        {
            pnlTrackList.Attributes["class"] = CurrentEditMode == EditMode.List ? "showPanel" : "hidePanel";
            pnlTrackDetails.Attributes["class"] = CurrentEditMode == EditMode.Edit ? "showPanel" : "hidePanel";
        }

        private void PopulateTrackDetails(Track track)
        {
            txtTracksName.Text = track.TrackName;
            cboTrackCategory.SelectedValue = track.TrackCategoryId.ToString();
            //gmap
            gMap1.Polylines.Clear();
            gMap1.Markers.Clear();
            List<LocationPoint> points = GeoUtils.DeserializeTrack(track.GeoString);
            //
            GooglePolyline polLine = new GooglePolyline();
            polLine.Color = Color.Fuchsia;
            polLine.Opacity = 1;
            polLine.EnableEditing = points.Count > 1;
            polLine.EnableDrawing = points.Count <= 1;
            points.ForEach(p => polLine.Points.Add(new GoogleLocation(p.Latitude, p.Longitude)));
            gMap1.Polylines.Add(polLine);
        }

        protected void btnSaveTrack_Click(object sender, EventArgs e)
        {
            //
            Track editedTrack = EditedTrack;
            editedTrack.TrackName = txtTracksName.Text;
            editedTrack.TrackCategoryId = Convert.ToInt32(cboTrackCategory.SelectedValue);

            if (gMap1.Polylines.Count > 0)
            {
                GooglePolyline polLine = gMap1.Polylines[0];
                if (polLine.Points.Count > 1)
                {
                    List<LocationPoint> locPoints = new List<LocationPoint>();
                    foreach (GoogleLocation point in polLine.Points)
                    {
                        locPoints.Add(new LocationPoint(point.Latitude, point.Longitude));
                    }
                    editedTrack.GeoString = GeoUtils.SerializeTrack(locPoints);
                }
            }

            TracksController.SaveTrack(editedTrack, editedTrack.Id == Guid.Empty ? true : false);

            ChangeDisplayMode(EditMode.List);
            gvTrackList.DataBind();
        }

        protected void btnSearchAddress_Click(object sender, ImageClickEventArgs e)
        {
            //search address
            string address = txtSearchAddress.Text;
            if (!string.IsNullOrEmpty(address))
                gMap1.Address = address;
        }

        protected void btnFitTrackInView_Click(object sender, ImageClickEventArgs e)
        {
            FitTrackInView();
        }

        private void FitTrackInView()
        {
            //fit points from track
            if (gMap1.Polylines.Count > 0)
            {
                GooglePolyline polLine = gMap1.Polylines[0];

                double latMax;
                double lonMin;
                double lonMax;
                double latCenter;
                double lonCenter;
                double latMin;
                GeoUtils2.GetCenterAndBounds(polLine, out latMin, out latMax, out lonMin, out lonMax, out latCenter, out lonCenter);

                // set the center
                gMap1.Latitude = latCenter;
                gMap1.Longitude = lonCenter;

                // set the map to call zoomMap javascriptFunction
                gMap1.OnClientMapLoad = "zoomMapX";

                // build zoomMap javascript function. I already know what my bounds are
                StringBuilder script = new StringBuilder();
                script.AppendFormat("<script>").AppendLine();
                script.Append("function zoomMap() {").AppendLine();
                script.AppendFormat("var sw = new GLatLng({0}, {1});", latMin, lonMin).AppendLine();
                script.AppendFormat("var ne = new GLatLng({0}, {1});", latMax, lonMax).AppendLine();
                script.AppendFormat("var bounds = new GLatLngBounds(sw, ne);").AppendLine();
                script.AppendFormat("var zoomLevel = {0}.get_map().getBoundsZoomLevel(bounds);", gMap1.ID).
                    AppendLine();
                script.AppendFormat("{0}.setZoom(zoomLevel);", gMap1.ID).AppendLine();
                script.Append("}").AppendLine();
                script.AppendFormat("</script>").AppendLine();

                ScriptManager.RegisterStartupScript(Page, this.GetType(), "map", script.ToString(), false);
                ScriptManager.RegisterStartupScript(Page, this.GetType(), "map2",
                                                    "function zoomMapX(){setTimeout('zoomMap()', 100);}", true);

            }
        }


        List<TrackCategory> listTrackCtagories = new List<TrackCategory>();
        protected string GetTrackCategory(int idTrackCategory)
        {
            if (listTrackCtagories.Count == 0)
                listTrackCtagories = TracksCategoriesController.GetTracksCategories();
            return listTrackCtagories.SingleOrDefault(p => p.Id == idTrackCategory).CategoryName;
        }

    }
}